package com.estore.service;

import com.estore.model.Product;
import java.io.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 商品服务类，负责商品相关的业务逻辑
 * 提供商品的增删改查、排序、库存管理等功能
 */
public class ProductService {

    // 使用Map存储商品数据，key是商品ID，value是商品对象
    private Map<String, Product> productData = new HashMap<>();
    // 从配置文件读取数据文件路径
    private String dataFilePath;
    // 配置文件路径
    private static final String CONFIG_FILE = "config.properties";

    private static final String DATA_FILE = "E:/estore_products.dat";
    /**
     * 构造函数，初始化商品数据
     */
    public ProductService() {
        // 首先加载配置
        loadConfig();
        // 然后尝试从文件加载数据
        loadData();

        // 如果加载的数据为空，则初始化示例数据
        if (productData.isEmpty()) {
            initializeSampleData();
        }
    }

    /**
     * 加载配置文件
     */
    private void loadConfig() {
        Properties props = new Properties();
        File configFile = new File(CONFIG_FILE);

        if (!configFile.exists()) {
            System.out.println("配置文件不存在，使用默认路径。");
            // 创建默认配置文件
            createDefaultConfig();
            // 重新加载
            loadConfig();
            return;
        }

        try (InputStreamReader reader = new InputStreamReader(
                new FileInputStream(CONFIG_FILE), "UTF-8")) {

            props.load(reader);
            dataFilePath = props.getProperty("data.file.path", "products.dat");
            System.out.println("配置文件加载成功，数据文件路径: " + dataFilePath);

        } catch (IOException e) {
            System.err.println("加载配置文件失败: " + e.getMessage());
            // 使用默认路径
            dataFilePath = "products.dat";
            System.out.println("使用默认数据文件路径: " + dataFilePath);
        }
    }

    /**
     * 创建默认配置文件
     */
    private void createDefaultConfig() {
        Properties props = new Properties();
        props.setProperty("data.file.path", "products.dat");
        props.setProperty("file.encoding", "UTF-8");

        try (OutputStreamWriter writer = new OutputStreamWriter(
                new FileOutputStream(CONFIG_FILE), "UTF-8")) {

            props.store(writer, "E-Store Configuration");
            System.out.println("已创建默认配置文件: " + CONFIG_FILE);

        } catch (IOException e) {
            System.err.println("创建配置文件失败: " + e.getMessage());
        }
    }


    /**
     * 初始化示例商品数据
     */
    private void initializeSampleData() {
        Set<String> tagsForJavaBook = new HashSet<>();
        tagsForJavaBook.add("编程");
        tagsForJavaBook.add("畅销");
        tagsForJavaBook.add("热门");

        // 为天官赐福创建标签
        Set<String> tagsForNovel = new HashSet<>();
        tagsForNovel.add("小说");
        tagsForNovel.add("热门");
        tagsForNovel.add("推荐");

        // 为生发秘籍创建标签
        Set<String> tagsForHair = new HashSet<>();
        tagsForHair.add("健康");
        tagsForHair.add("生活");
        tagsForHair.add("热门");

        // 添加初始商品数据
        addProduct(new Product("p001", "Java从入门到精通", 99.0, 100, tagsForJavaBook));
        addProduct(new Product("p002", "高性能MySQL", 128.5, 50));
        addProduct(new Product("p003", "颈椎康复指南", 45.0, 200));
        addProduct(new Product("p004", "生发秘籍", 88.0, 0, tagsForHair)); // 库存为0的商品
        addProduct(new Product("p005", "天官赐福", 199.0, 520, tagsForNovel));
        addProduct(new Product("p006", "蓝氏猫粮", 20.0, 10));
        addProduct(new Product("p007", "Python编程实战", 89.0, 75));
        addProduct(new Product("p008", "数据结构与算法", 120.0, 30));

        System.out.println("示例数据初始化完成，共添加 " + productData.size() + " 个商品");


        // 打印带标签的商品信息
        System.out.println("\n=== 带标签的商品信息 ===");
        for (Product product : productData.values()) {
            if (product.getTags() != null && !product.getTags().isEmpty()) {
                System.out.println(product);
            }
        }
    }

        /**
         * 保存数据到文件
         */
        public void saveData() {
            if (dataFilePath == null || dataFilePath.trim().isEmpty()) {
                System.err.println("数据文件路径未配置，无法保存数据");
                return;
            }

            try {
                // 确保目录存在
                File file = new File(dataFilePath);
                File parentDir = file.getParentFile();
                if (parentDir != null && !parentDir.exists()) {
                    boolean dirsCreated = parentDir.mkdirs();
                    if (!dirsCreated) {
                        System.err.println("无法创建目录: " + parentDir.getAbsolutePath());
                    }
                }
                // 保存数据
                try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(dataFilePath))) {
                    oos.writeObject(productData);
                    System.out.println("商品数据已保存到文件: " + dataFilePath);
                    System.out.println("保存了 " + productData.size() + " 个商品");
                }
            } catch (Exception e) {
                System.err.println("保存数据失败: " + e.getClass().getName() + ": " + e.getMessage());
                e.printStackTrace();
            }
        }

        /**
         * 从文件加载数据
         */
        @SuppressWarnings("unchecked")
        public void loadData() {
            if (dataFilePath == null || dataFilePath.trim().isEmpty()) {
                System.out.println("数据文件路径未配置，无法加载数据");
                return;
            }

            File file = new File(dataFilePath);
            if (!file.exists()) {
                System.out.println("数据文件不存在，将创建新的数据存储。");
                return;
            }

            try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(dataFilePath))) {
                Object obj = ois.readObject();
                if (obj instanceof Map) {
                    productData = (Map<String, Product>) obj;
                    System.out.println("商品数据已从文件加载: " + dataFilePath);
                    System.out.println("加载了 " + productData.size() + " 个商品");
                }
            } catch (Exception e) {
                System.err.println("加载数据失败: " + e.getClass().getName() + ":" + e.getMessage());
                e.printStackTrace();
                // 如果加载失败，保持空的products映射
                productData = new HashMap<>();
            }
        }


    /**
     * 更新配置文件中的路径
     */
    public void updateConfig(String newFilePath) {
        Properties props = new Properties();

        // 先读取现有配置
        File configFile = new File(CONFIG_FILE);
        if (configFile.exists()) {
            try (InputStreamReader reader = new InputStreamReader(
                    new FileInputStream(CONFIG_FILE), "UTF-8")) {
                props.load(reader);
            } catch (IOException e) {
                System.err.println("读取现有配置失败: " + e.getMessage());
            }
        }

        // 更新路径
        props.setProperty("data.file.path", newFilePath);

        // 保存配置
        try (OutputStreamWriter writer = new OutputStreamWriter(
                new FileOutputStream(CONFIG_FILE), "UTF-8")) {

            props.store(writer, "E-Store Configuration");
            dataFilePath = newFilePath;
            System.out.println("配置文件已更新，新数据文件路径: " + dataFilePath);

        } catch (IOException e) {
            System.err.println("更新配置文件失败: " + e.getMessage());
        }
    }

    /**
     * 获取当前数据文件路径
     */
    public String getDataFilePath() {
        return dataFilePath;
    }


    /**
     * 获取所有商品列表
     * @return 商品列表（不可修改的副本）
     */
    public List<Product> getAllProducts() {
        return Collections.unmodifiableList(new ArrayList<>(productData.values()));
    }

    /**
     * 获取所有商品列表（可修改的副本）
     * @return 商品列表的副本
     */
    public List<Product> getAllProductsCopy() {
        return new ArrayList<>(productData.values());
    }

    /**
     * 根据ID查找商品
     * @param id 商品ID
     * @return 找到的商品对象，如果不存在则返回null
     */
    public Product findProductById(String id) {
        if (id == null || id.trim().isEmpty()) {
            return null;
        }
        return productData.get(id.toLowerCase());
    }

    /**
     * 添加新商品
     * @param product 商品对象
     * @return 添加成功返回true，如果商品ID已存在返回false
     */
    public boolean addProduct(Product product) {
        if (product == null || product.getId() == null) {
            return false;
        }
        String id = product.getId().toLowerCase();
        if (productData.containsKey(id)) {
            return false; // 商品ID已存在
        }
        productData.put(id, product);
        return true;
    }

    /**
     * 更新商品信息
     * @param product 商品对象
     * @return 更新成功返回true，如果商品不存在返回false
     */
    public boolean updateProduct(Product product) {
        if (product == null || product.getId() == null) {
            return false;
        }
        String id = product.getId().toLowerCase();
        if (!productData.containsKey(id)) {
            return false; // 商品不存在
        }
        productData.put(id, product);
        return true;
    }

    /**
     * 删除商品
     * @param id 商品ID
     * @return 删除成功返回被删除的商品，如果商品不存在返回null
     */
    public Product deleteProduct(String id) {
        if (id == null) {
            return null;
        }
        return productData.remove(id.toLowerCase());
    }

    /**
     * 检查商品是否存在
     * @param id 商品ID
     * @return 存在返回true，否则返回false
     */
    public boolean productExists(String id) {
        return id != null && productData.containsKey(id.toLowerCase());
    }

    /**
     * 根据名称搜索商品（模糊匹配）
     * @param name 商品名称关键词
     * @return 匹配的商品列表
     */
    public List<Product> searchProductsByName(String name) {
        if (name == null || name.trim().isEmpty()) {
            return Collections.emptyList();
        }

        String keyword = name.toLowerCase().trim();
        return productData.values().stream()
                .filter(product -> product.getName().toLowerCase().contains(keyword))
                .collect(Collectors.toList());
    }

    /**
     * 根据标签搜索商品
     * @param tag 标签名称
     * @return 包含该标签的商品列表
     */
    public List<Product> searchProductsByTag(String tag) {
        if (tag == null || tag.trim().isEmpty()) {
            return Collections.emptyList();
        }

        String tagKeyword = tag.toLowerCase().trim();
        return productData.values().stream()
                .filter(product -> product.getTags() != null &&
                        product.getTags().stream()
                                .anyMatch(t -> t.toLowerCase().contains(tagKeyword)))
                .collect(Collectors.toList());
    }

    /**
     * 获取有库存的商品列表
     * @return 库存大于0的商品列表
     */
    public List<Product> getAvailableProducts() {
        return productData.values().stream()
                .filter(product -> product.getStock() > 0)
                .collect(Collectors.toList());
    }

    /**
     * 获取缺货的商品列表
     * @return 库存为0的商品列表
     */
    public List<Product> getOutOfStockProducts() {
        return productData.values().stream()
                .filter(product -> product.getStock() == 0)
                .collect(Collectors.toList());
    }

    /**
     * 根据价格范围筛选商品
     * @param minPrice 最低价格
     * @param maxPrice 最高价格
     * @return 价格在指定范围内的商品列表
     */
    public List<Product> getProductsByPriceRange(double minPrice, double maxPrice) {
        if (minPrice < 0 || maxPrice < minPrice) {
            return Collections.emptyList();
        }

        return productData.values().stream()
                .filter(product -> product.getPrice() >= minPrice && product.getPrice() <= maxPrice)
                .collect(Collectors.toList());
    }

    /**
     * 更新商品库存
     * @param id 商品ID
     * @param newStock 新的库存数量
     * @return 更新成功返回true，商品不存在或库存为负数返回false
     */
    public boolean updateStock(String id, int newStock) {
        if (newStock < 0) {
            return false;
        }

        Product product = findProductById(id);
        if (product == null) {
            return false;
        }

        product.setStock(newStock);
        return true;
    }

    /**
     * 减少商品库存
     * @param id 商品ID
     * @param quantity 减少的数量
     * @return 操作成功返回true，库存不足或商品不存在返回false
     */
    public boolean reduceStock(String id, int quantity) {
        if (quantity <= 0) {
            return false;
        }

        Product product = findProductById(id);
        if (product == null || product.getStock() < quantity) {
            return false;
        }

        product.setStock(product.getStock() - quantity);
        return true;
    }

    /**
     * 增加商品库存
     * @param id 商品ID
     * @param quantity 增加的数量
     * @return 操作成功返回true，商品不存在返回false
     */
    public boolean increaseStock(String id, int quantity) {
        if (quantity <= 0) {
            return false;
        }

        Product product = findProductById(id);
        if (product == null) {
            return false;
        }

        product.setStock(product.getStock() + quantity);
        return true;
    }

    /**
     * 为商品添加标签
     * @param id 商品ID
     * @param tag 标签
     * @return 添加成功返回true，商品不存在返回false
     */
    public boolean addTagToProduct(String id, String tag) {
        Product product = findProductById(id);
        if (product == null) {
            return false;
        }

        if (product.getTags() == null) {
            product.setTags(new HashSet<>());
        }

        return product.getTags().add(tag);
    }

    /**
     * 从商品移除标签
     * @param id 商品ID
     * @param tag 标签
     * @return 移除成功返回true，商品不存在或标签不存在返回false
     */
    public boolean removeTagFromProduct(String id, String tag) {
        Product product = findProductById(id);
        if (product == null || product.getTags() == null) {
            return false;
        }

        return product.getTags().remove(tag);
    }

    /**
     * 获取商品总数
     * @return 商品总数
     */
    public int getTotalProductCount() {
        return productData.size();
    }

    /**
     * 获取有库存的商品数量
     * @return 有库存的商品数量
     */
    public int getAvailableProductCount() {
        return (int) productData.values().stream()
                .filter(product -> product.getStock() > 0)
                .count();
    }

    /**
     * 获取所有商品的总价值
     * @return 商品总价值（价格 × 库存）
     */
    public double getTotalInventoryValue() {
        return productData.values().stream()
                .mapToDouble(product -> product.getPrice() * product.getStock())
                .sum();
    }

    /**
     * 获取最贵的商品
     * @return 价格最高的商品，如果没有商品返回null
     */
    public Product getMostExpensiveProduct() {
        return productData.values().stream()
                .max(Comparator.comparingDouble(Product::getPrice))
                .orElse(null);
    }

    /**
     * 获取最便宜的商品
     * @return 价格最低的商品，如果没有商品返回null
     */
    public Product getCheapestProduct() {
        return productData.values().stream()
                .min(Comparator.comparingDouble(Product::getPrice))
                .orElse(null);
    }

    /**
     * 清空所有商品数据（用于测试或重置）
     */
    public void clearAllProducts() {
        productData.clear();
    }

    /**
     * 重新初始化示例数据
     */
    public void resetToSampleData() {
        productData.clear();
        initializeSampleData();
    }
    /**
     * 备份数据文件
     * 使用基础的 FileInputStream 和 FileOutputStream 进行字节级复制
     */
    public boolean backupData() {
        if (dataFilePath == null || dataFilePath.trim().isEmpty()) {
            System.err.println("数据文件路径未配置，无法备份");
            return false;
        }

        File sourceFile = new File(dataFilePath);
        if (!sourceFile.exists()) {
            System.err.println("源数据文件不存在，无法备份: " + dataFilePath);
            return false;
        }

        String backupFilePath = dataFilePath + ".bak";
        File backupFile = new File(backupFilePath);

        // 使用基础的字节流进行文件复制
        try (FileInputStream fis = new FileInputStream(sourceFile);
             FileOutputStream fos = new FileOutputStream(backupFile)) {

            // 创建缓冲区
            byte[] buffer = new byte[1024];
            int bytesRead;

            // 循环读取和写入数据
            while ((bytesRead = fis.read(buffer)) != -1) {
                fos.write(buffer, 0, bytesRead);
            }

            System.out.println("数据备份成功！");
            System.out.println("源文件: " + dataFilePath);
            System.out.println("备份文件: " + backupFilePath);
            System.out.println("文件大小: " + sourceFile.length() + " 字节");

            return true;

        } catch (IOException e) {
            System.err.println("备份数据失败: " + e.getMessage());
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 从备份文件恢复数据
     */
    public boolean restoreFromBackup() {
        if (dataFilePath == null || dataFilePath.trim().isEmpty()) {
            System.err.println("数据文件路径未配置，无法恢复");
            return false;
        }

        String backupFilePath = dataFilePath + ".bak";
        File backupFile = new File(backupFilePath);

        if (!backupFile.exists()) {
            System.err.println("备份文件不存在: " + backupFilePath);
            return false;
        }

        File targetFile = new File(dataFilePath);

        // 使用基础的字节流进行文件复制
        try (FileInputStream fis = new FileInputStream(backupFile);
             FileOutputStream fos = new FileOutputStream(targetFile)) {

            // 创建缓冲区
            byte[] buffer = new byte[1024];
            int bytesRead;

            // 循环读取和写入数据
            while ((bytesRead = fis.read(buffer)) != -1) {
                fos.write(buffer, 0, bytesRead);
            }

            // 重新加载数据
            loadData();

            System.out.println("数据恢复成功！");
            System.out.println("从备份文件: " + backupFilePath);
            System.out.println("恢复到: " + dataFilePath);

            return true;

        } catch (IOException e) {
            System.err.println("恢复数据失败: " + e.getMessage());
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 检查备份文件是否存在
     */
    public boolean backupExists() {
        if (dataFilePath == null || dataFilePath.trim().isEmpty()) {
            return false;
        }

        String backupFilePath = dataFilePath + ".bak";
        File backupFile = new File(backupFilePath);

        return backupFile.exists();
    }

    /**
     * 获取备份文件信息
     */
    public String getBackupInfo() {
        if (!backupExists()) {
            return "暂无备份文件";
        }

        String backupFilePath = dataFilePath + ".bak";
        File backupFile = new File(backupFilePath);

        return String.format("备份文件: %s (大小: %d 字节, 最后修改: %s)",
                backupFilePath,
                backupFile.length(),
                new java.util.Date(backupFile.lastModified()));
    }
}